home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 6
/
QRZ Ham Radio Callsign Database - Volume 6.iso
/
mac
/
files
/
amiga
/
rhinosrc.lha
/
udpsock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-11
|
3KB
|
172 lines
#include "global.h"
#include "udp.h"
#include "socket.h"
#include "usock.h"
static void s_urcall __ARGS((struct iface *iface,struct udp_cb *udp,int cnt));
static void autobind __ARGS((struct usock *up));
int
so_udp(up,protocol)
struct usock *up;
int protocol;
{
return 0;
}
int
so_udp_bind(up)
struct usock *up;
{
int s;
struct sockaddr_in *sp;
struct socket lsock;
s = up->index;
sp = (struct sockaddr_in *)up->name;
lsock.address = sp->sin_addr.s_addr;
lsock.port = sp->sin_port;
up->cb.udp = open_udp(&lsock,s_urcall);
up->cb.udp->user = s;
return 0;
}
int
so_udp_conn(up)
struct usock *up;
{
if(up->name == NULLCHAR){
autobind(up);
}
return 0;
}
int
so_udp_recv(up,bpp,from,fromlen)
struct usock *up;
struct mbuf **bpp;
char *from;
int *fromlen;
{
int cnt;
struct udp_cb *udp;
struct sockaddr_in *remote;
struct socket fsocket;
while((udp = up->cb.udp) != NULLUDP
&& (cnt = recv_udp(udp,&fsocket,bpp)) == -1){
if(up->noblock){
errno = EWOULDBLOCK;
return -1;
} else if((errno = pwait(up)) != 0){
return -1;
}
}
if(udp == NULLUDP){
/* Connection went away */
errno = ENOTCONN;
return -1;
}
if(from != NULLCHAR && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
remote = (struct sockaddr_in *)from;
remote->sin_family = AF_INET;
remote->sin_addr.s_addr = fsocket.address;
remote->sin_port = fsocket.port;
*fromlen = SOCKSIZE;
}
return cnt;
}
int
so_udp_send(up,bp,to)
struct usock *up;
struct mbuf *bp;
char *to;
{
struct sockaddr_in *local,*remote;
struct socket lsock,fsock;
if(up->name == NULLCHAR)
autobind(up);
local = (struct sockaddr_in *)up->name;
lsock.address = local->sin_addr.s_addr;
lsock.port = local->sin_port;
if(to != NULLCHAR) {
remote = (struct sockaddr_in *)to;
} else if(up->peername != NULLCHAR){
remote = (struct sockaddr_in *)up->peername;
} else {
free_p(bp);
errno = ENOTCONN;
return -1;
}
fsock.address = remote->sin_addr.s_addr;
fsock.port = remote->sin_port;
send_udp(&lsock,&fsock,up->tos,0,bp,0,0,0);
return 0;
}
int
so_udp_qlen(up,rtx)
struct usock *up;
int rtx;
{
int len;
switch(rtx){
case 0:
len = up->cb.udp->rcvcnt;
break;
case 1:
len = 0;
break;
}
return len;
}
int
so_udp_close(up)
struct usock *up;
{
if(up->cb.udp != NULLUDP){
del_udp(up->cb.udp);
}
return 0;
}
int
so_udp_shut(up,how)
struct usock *up;
int how;
{
int s;
s = up->index;
close_s(s);
return 0;
}
static void
s_urcall(iface,udp,cnt)
struct iface *iface;
struct udp_cb *udp;
int cnt;
{
psignal(itop(udp->user),1);
pwait(NULL);
}
/* Issue an automatic bind of a local address */
static void
autobind(up)
struct usock *up;
{
struct sockaddr_in local;
int s;
s = up->index;
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = Lport++;
bind(s,(char *)&local,sizeof(struct sockaddr_in));
}
int
so_udp_stat(up)
struct usock *up;
{
st_udp(up->cb.udp,0);
return 0;
}